<?php

namespace App\Http\Controllers\TK_Api;

use App\Events\UserLearnVideoChangeEvent;
use App\Http\Requests\QH\QHLearnVideoLimitFreeStoreRequest;
use App\Http\Requests\TK\DeleteUserBindQuestionRequest;
use App\Http\Requests\TK\UpdateUserInfoRequest;
use App\Models\Coupon;
use App\Models\CourseColumn;
use App\Models\KnowledgePost;
use App\Models\LearnVideo;
use App\Models\Note;
use App\Models\Order;
use App\Models\Qh_Course;
use App\Models\Qh_Knowledge;
use App\Models\Qh_Question;
use App\Models\Qh_UserCollectQuestion;
use App\Models\Questions;
use App\Service\Redis\RedisBaseService;
use Carbon\Carbon;
use DB;
use Illuminate\Http\JsonResponse;

class UserController extends ApiBaseController
{

    /**
     * 获取用户信息
     * @return JsonResponse|object
     */
    public function getInfo() {
        return $this->restful([
            'id' => $this->user->id,
            'username' => $this->user->username,
            'nickname' => $this->user->nickname,
            'avatar' => $this->user->avatar,
            // 'avatar' => '',
            'gender' => $this->user->gender,
            'province' => $this->user->province
        ]);
    }

    /**
     * 更新用户信息
     * @param UpdateUserInfoRequest $request
     * @return JsonResponse|object
     */
    public function updateInfo(UpdateUserInfoRequest $request) {
        $params = $request->validated();

        $this->user->username = !empty($params['username']) ? $params['username'] : null;
        $this->user->nickname = $params['nickname'];
        $this->user->avatar = $params['avatar'];
        $this->user->mobile = !empty($params['mobile']) ? $params['mobile'] : $this->user->mobile;
        $this->user->gender = !empty($params['gender']) ? $params['gender'] : $this->user->gender;
        $this->user->ksCountdown = !empty($params['countdown']) ? $params['countdown'] : $this->user->ksCountdown;
        if (!empty($params['province'])) {
            $this->user->province = $params['province'];
        }

        $this->user->save();

        return $this->restful([
            'id' => $this->user->id,
            'username' => $this->user->username ?? $this->user->nickname,
            'nickname' => $this->user->nickname,
            'mobile' => $this->user->mobile,
            'avatar' => $this->user->avatar,
            'gender' => $this->user->gender,
            'province' => $this->user->province,
            'ksCountdown' => $this->user->ksCountdown ?? null,
            'ksCountdownDays' => $this->user->ksCountdown ? Carbon::now()->diffInDays(Carbon::make($this->user->ksCountdown)) : null,
            'ksDaysCount' => $this->user->ksDaysCount ?? 0,
        ]);
    }

    /**
     * 获取用户收藏的题目，返回前50个ids
     * @return JsonResponse|object
     */
    public function getCollect() {
        $list = null;
        $data = Db::table('tiku_user_collect')->where('userId', $this->user->id)->where('type', 1)->first();
        if ($data) {
            $ids = explode(',', $data->ids);
            if (count($ids) > 50) {
                $ids = array_slice($ids, -50);
                $data->update(['ids' => implode(',', $ids)]);
                $data->save();
            }
            $_list = Questions::whereIn('tiku_questions1.id', $ids)
                ->join('tiku_course', 'tiku_questions1.courseId',  '=',  'tiku_course.id')
                ->join('tiku_knowledge', 'tiku_questions1.thirdKnowledgeId',  '=',  'tiku_knowledge.id')
                ->select(['tiku_questions1.id', 'tiku_questions1.courseId', 'tiku_knowledge.knowledgeName', 'tiku_course.fullName as courseName', 'tiku_questions1.bodyhtml as title',])
                ->orderBy('tiku_questions1.id')
                ->limit(50)->get();

            $list = [];
            foreach ($_list as $item) {
                $item['title'] = replaceStaticFileUrlInString($item['title']);
                $course = array_column($list, 'courseName');
                $searchResult = array_search($item['courseName'], $course);
                if($searchResult === false) {
                    $list[] = [
                        'courseName' => $item['courseName'],
                        'data' => [$item]
                    ];
                }
                elseif (array_key_exists($searchResult, $course)) {
                    $list[$searchResult]['data'][] = $item;
                }
                else {
                    $list[] = [
                        'courseName' => $item['courseName'],
                        'data' => [$item]
                    ];
                }
            }
        }

        $list = [
            'ids' => $data ? explode(',', $data->ids) : [],
            'data' => $list
        ];

        return $this->restful($list);
    }

    /**
     * 取用户错题，返回前50个ids
     * @return JsonResponse|object
     */
    public function getCuoti() {
        $list = null;
        $data = Db::table('tiku_user_cuoti')->where('userId', $this->user->id)->first();
        if ($data) {
            $ids = explode(',', $data->ids);
            if (count($ids) > 50) {
                $ids = array_slice($ids, -50);
                $data->update(['ids' => implode(',', $ids)]);
                $data->save();
            }
            $_list = Questions::whereIn('tiku_questions1.id', $ids)
                ->join('tiku_course', 'tiku_questions1.courseId',  '=',  'tiku_course.id')
                ->join('tiku_knowledge', 'tiku_questions1.thirdKnowledgeId',  '=',  'tiku_knowledge.id')
                ->select(['tiku_questions1.id', 'tiku_questions1.courseId', 'tiku_knowledge.knowledgeName', 'tiku_course.fullName as courseName', 'tiku_questions1.bodyhtml as title',])
                ->orderBy('tiku_questions1.id', 'asc')
                ->limit(50)->get();

            $list = [];
            foreach ($_list as $item) {
                $item['title'] = replaceStaticFileUrlInString($item['title']);
                $course = array_column($list, 'courseName');
                $searchResult = array_search($item['courseName'], $course);
                if($searchResult === false) {
                    $list[] = [
                        'courseName' => $item['courseName'],
                        'data' => [$item]
                    ];
                }
                elseif (array_key_exists($searchResult, $course)) {
                    $list[$searchResult]['data'][] = $item;
                }
                else {
                    $list[] = [
                        'courseName' => $item['courseName'],
                        'data' => [$item]
                    ];
                }
            }
        }

        $list = [
            'ids' => $data ? explode(',', $data->ids) : [],
            'data' => $list
        ];

        return $this->restful($list);
    }

    /**
     * 获取收藏的知识点文章
     * @return JsonResponse|object
     */
    public function getCollectKnowledgePost() {
        $list = null;
        $ids = $this->user->knowledgePost()->pluck('postId');
        if ($ids) {
            $_list = KnowledgePost::whereIn('tiku_knowledge_post.id', $ids)
                ->join('tiku_knowledge', 'tiku_knowledge_post.knowledgeId',  '=',  'tiku_knowledge.id')
                ->join('tiku_course', 'tiku_knowledge.courseId',  '=',  'tiku_course.id')
                ->select(['tiku_knowledge_post.id', 'tiku_knowledge_post.title', 'tiku_knowledge.knowledgeName', 'tiku_course.fullName as courseName'])
                ->orderBy('tiku_knowledge_post.id')
                ->limit(50)->get();

            $list = [];
            foreach ($_list as $item) {
                $item['title'] = replaceStaticFileUrlInString($item['title']);
                $course = array_column($list, 'courseName');
                $searchResult = array_search($item['courseName'], $course);
                if($searchResult === false) {
                    $list[] = [
                        'courseName' => $item['courseName'],
                        'data' => [$item]
                    ];
                }
                elseif (array_key_exists($searchResult, $course)) {
                    $list[$searchResult]['data'][] = $item;
                }
                else {
                    $list[] = [
                        'courseName' => $item['courseName'],
                        'data' => [$item]
                    ];
                }
            }
        }

        $list = [
            'ids' => $ids ?? [],
            'data' => $list
        ];

        return $this->restful($list);
    }

    /**
     * 删除收藏
     * @param DeleteUserBindQuestionRequest $request
     * @return JsonResponse|object
     */
    public function delCollect(DeleteUserBindQuestionRequest $request) {
        $params = $request->validated();
        $id = $params['id'];
        $collect = Db::table('tiku_user_collect')->where('userId', $this->user->id)->where('type', 1)->first();
        if ($collect) {
            $ids = explode(',', $collect->ids);
            if (in_array($id, $ids)) {
                unset($ids[array_search($id, $ids)]);
                Db::table('tiku_user_collect')->where('userId', $this->user->id)->where('type', 1)->update([
                    'ids' => implode(',', $ids)
                ]);
            }
        }

        return $this->restful();
    }

    /**
     * 删除错题
     * @param DeleteUserBindQuestionRequest $request
     * @return JsonResponse|object
     */
    public function delCuoti(DeleteUserBindQuestionRequest $request) {
        $params = $request->validated();
        $id = $params['id'];
        $cuoti = Db::table('tiku_user_cuoti')->where('userId', $this->user->id)->first();
        if ($cuoti) {
            $ids = explode(',', $cuoti->ids);
            if (in_array($id, $ids)) {
                unset($ids[array_search($id, $ids)]);
                Db::table('tiku_user_cuoti')->where('userId', $this->user->id)->update([
                    'ids' => implode(',', $ids)
                ]);
            }
        }

        return $this->restful();
    }

    /**
     * 删除收藏的知识点文章
     * @param DeleteUserBindQuestionRequest $request
     * @return JsonResponse|object
     */
    public function delKnowledgePost(DeleteUserBindQuestionRequest $request) {
        $params = $request->validated();
        $id = $params['id'];

        $this->user->knowledgePost()->detach($id);

        return $this->restful();
    }

    /**
     * 获取统计数据
     * @return JsonResponse|object
     */
    public function statistics() {
        $cuotiIds = DB::table('tiku_user_cuoti')->where('userId', $this->user->id)->value('ids');
        $cuotiCount = count(explode(',', $cuotiIds));

        $collectIds = DB::table('tiku_user_collect')->where('userId', $this->user->id)->where('type', 1)->value('ids');
        $collectCount = count(explode(',', $collectIds));

        $collectKnowledgeCount = $this->user->knowledgePost()->count();

        return $this->restful([
            'cuotiCount' => $cuotiCount,
            'collectCount' => $collectCount,
            'collectKnowledgeCount' => $collectKnowledgeCount,
        ]);
    }


    /**
     * 获取我的兑换记录
     * @return JsonResponse|object
     */
    public function getMyQuestionLibraryBuyLogForCdkey() {
        $list = DB::table('qh_user_has_course')
            ->selectRaw('
                qh_courses.id,
                qh_courses.name,
                qh_cdkeys.code as cdkey,
                qh_cdkeys.useAt,
                qh_cdkeys.created_at as buyAt
            ')
            ->join('qh_courses', 'qh_user_has_course.courseId', '=', 'qh_courses.id')
            ->join('qh_cdkeys', 'qh_user_has_course.sourceId', '=', 'qh_cdkeys.id')
            ->where('qh_user_has_course.userId', $this->user->id)
            ->where('qh_user_has_course.type', 2)
            ->orderByDesc('qh_user_has_course.created_at')
            ->get();

        return $this->restful($list);
    }

    /**
     * 获取我收藏的试题
     * @return JsonResponse|object
     */
    public function getMyCollectQuestion() {
        $qIds = Qh_UserCollectQuestion::where('userId', $this->user->id)->orderByDesc('id')->pluck('questionId')->toArray();

        $list = Qh_Question::whereIn('id', $qIds)->get();

        return $this->restful($list);
    }

    /**
     * 获取我的收藏题 v2版本
     * @return JsonResponse|object
     */
    public function getMyCollectQuestionV2() {
        return $this->restful((new RedisBaseService())->getUserWrongOrCollectQuestionData($this->user->id, 2));
    }

    /**
     * 获取我的错题
     * @return JsonResponse|object
     */
    public function getMyCuoti() {
        $qIds = DB::table('qh_user_question_logs')->where('userId', $this->user->id)->where('result', 2)->orderByDesc('id')->pluck('questionId')->toArray();

        $list = Qh_Question::whereIn('id', $qIds)->paginate(10);

        return $this->restful($list);
    }

    /**
     * 获取我的错题 v2版本
     * @return JsonResponse|object
     * @throws \RedisException
     */
    public function getMyCuotiV2()
    {
        return $this->restful((new RedisBaseService())->getUserWrongOrCollectQuestionData($this->user->id, 1));
    }

    /**
     * 删除我的错题/收藏
     * @param RedisBaseService $redisBaseService
     * @return JsonResponse|object
     * @throws \RedisException
     */
    public function deleteUserQuestion(RedisBaseService $redisBaseService) {
        $mode = request('mode');    // 1：单题、2：学科、3：章、4：节
        $type = request('type', 1); // 1：错题、2：收藏
        $id = request('id');

        if (empty($mode) || empty($id)) return $this->restful(null, false, '删除失败');

        $redisBaseService->deleteUserWrongOrCollectQuestionData($this->user->id, $id, $mode, $type);

        return $this->restful();
    }

    /**
     * 获取我的笔记
     * @return JsonResponse|object
     */
    public function getMyNote() {
        $notes = Note::where('userId', $this->user->id)
            ->selectRaw('notes.*, qh_questions.qlId, qh_questions.courseId, qh_questions.knowledgeId')
            ->join('qh_questions', 'notes.questionId', '=', 'qh_questions.id')
            ->orderByDesc('id')
            ->get();

        return $this->restful($notes);
    }

    /**
     * 删除我的笔记
     * @param $id
     * @return JsonResponse|object
     */
    public function deleteMyNote($id) {
        $result = Note::where('id', $id)->where('userId', $this->user->id)->delete();

        return $this->restful($result);
    }

    /**
     * 获取关注的院校
     * @return JsonResponse|object
     */
    public function getMyFollowSchool() {
        $list = $this->user->followedSchool;

        return $this->restful($list);
    }


    /**
     * 检测用户是否拥有该题的访问权限（可以单题或根据知识点来判断）
     * @return JsonResponse|object
     */
    public function userHaveQuestionAuthCheck()
    {
        $type = request('type');
        $id = request('id');
        if (empty($type) || empty($id)) return $this->restful(false);
        if ($type != 1 && $type != 2) return $this->restful(false);

        // 单题模式
        if ($type == 1) {
            // 获取题
            $question = Qh_Question::find($id);
            if (!$question) return $this->restful(false);
            $courseId = $question->courseId;
        }
        // 知识点模式
        else {
            $knowledge = Qh_Knowledge::find($id);
            if (!$knowledge) return $this->restful(false);
            $courseId = $knowledge->courseId;
        }

        $course = Qh_Course::find($courseId);
        if ($course->amount > 0) {
            $userCourseIds = DB::table('qh_user_has_course')->where('userId', $this->user->id)->pluck('courseId')->toArray();
            if (!in_array($courseId, $userCourseIds)) return $this->restful(false);
        }

        return $this->restful(true);
    }

    /**
     * 获取用户优惠券列表
     * @return JsonResponse|object
     */
    public function getCoupons()
    {
        $couponIds = DB::table('user_coupon')->where('userId', $this->user->id)->pluck('couponId')->toArray();
        $coupons = Coupon::whereIn('id', $couponIds)->get();

        return $this->restful($coupons);
    }

    /**
     * 领取优惠券
     * @return JsonResponse|object
     * @throws \Exception
     */
    public function storeCoupon()
    {
        $params = request()->validate([
            'couponId' => 'bail|required|int',
        ], request()->all());

        $exists = DB::table('user_coupon')->where('userId', $this->user->id)->where('couponId', $params['couponId'])->exists();
        if ($exists) throw new \Exception('已领取过了');

        $coupon = Coupon::find($params['couponId']);
        if (!$coupon) throw new \Exception('优惠券不存在');

        if ($coupon->is_active != 1) throw new \Exception('优惠券无效');
        if ($coupon->stop_get && Carbon::make($coupon->stop_get)->lt(now())) throw new \Exception('优惠券不存在');

        DB::table('user_coupon')->insert([
            'userId' => $this->user->id,
            'couponId' => $params['couponId'],
            'getAt' => now(),
            'created_at' => now(),
            'updated_at' => now()
        ]);

        return $this->restful($coupon);
    }

    /**
     * @return JsonResponse|object
     */
    public function cancelOrder()
    {
        $id = request('id');
        if ($id) {
            Order::where('id', $id)->where('userId', $this->user->id)->update(['status' => 5]);
        }

        return $this->restful();
    }

        //添加课程限免记录
    public function learnVideoLimitFreeStore(QHLearnVideoLimitFreeStoreRequest $request)
    {
        $params = $request->validated();
        if ($params['sourceType'] == 1) {
               $exists = DB::table('user_learn_video_logs')
                   ->where('userId', $this->user->id)
                   ->where('learnVideoId', $params['learnVideoId'])
                   ->exists();
               if (!$exists) {
                   DB::table('user_learn_video_logs')->insert([
                       'userId' => $this->user->id,
                       'learnVideoId' => $params['learnVideoId'],
                       'getType' => 3, // 限免
                       'isTry' => 1,
                       'getAt' => now(),
                       'expireAt' => now()
                   ]);
                   event(new UserLearnVideoChangeEvent($this->user->id));
               }
        }

        return $this->restful();
    }

    /**
     * 获取网课兑换记录
     * @return JsonResponse|object
     */
    public function getNetCourseCdekyUserLog()
    {
        $learnVideo = LearnVideo::select([
            'learn_videos.*',
            'user_learn_video_logs.userId',
            'user_learn_video_logs.getAt',
            'user_learn_video_logs.getType',
            'user_learn_video_logs.isTry',
            'user_learn_video_logs.expireAt',
        ])
            ->join('user_learn_video_logs', 'learn_videos.id', '=', 'user_learn_video_logs.learnVideoId')
            ->where('user_learn_video_logs.userId', $this->user->id)
            ->where('user_learn_video_logs.isTry', 0)
            ->orderByDesc('user_learn_video_logs.getAt')
            ->get();
        foreach ($learnVideo as $item) {
            $item->resourceType = '单科';
            if ($item->expireAt) {
                if (Carbon::make($item->expireAt)->diffInYears(now()) > 90) $item->expireAt2 = '长期';
                else $item->expireAt2 = Carbon::make($item->expireAt)->format('Y-m-d');
            }
        }

        $courseColumn = CourseColumn::select([
            'course_columns.*',
            'user_course_column_buy_logs.userId',
            'user_course_column_buy_logs.created_at as getAt',
            'user_course_column_buy_logs.getType',
            'user_course_column_buy_logs.expireAt',
        ])
            ->join('user_course_column_buy_logs', 'course_columns.id', '=', 'user_course_column_buy_logs.dataId')
            ->where('user_course_column_buy_logs.userId', $this->user->id)
            ->where('user_course_column_buy_logs.getType', 2)
            ->orderByDesc('user_course_column_buy_logs.id')
            ->get();

        foreach ($courseColumn as $item) {
            $item->resourceType = '专栏';
            $item->getTypeText = '激活';
            if ($item->expireAt) {
                $item->statusText = Carbon::make($item->expireAt)->gt(now()) ? '生效中' : '已过期';
                if (Carbon::make($item->expireAt)->diffInYears(now()) > 90) $item->expireAt2 = '长期';
                else $item->expireAt2 = Carbon::make($item->expireAt)->format('Y-m-d');
            }else {
                $item->expireAt2 = '-';
                $item->statusText = '已过期';
            }
        }

        $list = array_merge($learnVideo->toArray(), $courseColumn->toArray());
        usort($list, function ($a, $b) {
            if ($a['getAt'] == $b['getAt']) {
                return 0;
            }
            return ($a['getAt'] > $b['getAt']) ? -1 : 1;
        });

        return $this->restful($list);
    }
}
